package com.example.understandvideo.service;

import com.example.understandvideo.mapper.SettingDao;
import com.example.understandvideo.pojo.*;
import com.example.understandvideo.tool.*;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.io.*;
import java.lang.management.ManagementPermission;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


@Service
@Slf4j
public class DemoService {
    @Autowired
    CommonService service;
    @Resource
    private OCRProcessor ocrProcessor;

    public void postWord() {
        Gson gson = new Gson();
        String inputFilePath = "C:\\Users\\xjc.ARCVIDEO\\Downloads\\inputs.docx";
        String outputFilePath = "C:\\Users\\xjc.ARCVIDEO\\Downloads\\test - 2-output.docx";
        String reFilePath = "C:\\Users\\xjc.ARCVIDEO\\Downloads\\test - 2-output.docx";
        String searchString = "##test##";
        String questionContent = null;
        List<String> data = new ArrayList<>();
        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument document = new XWPFDocument(fis)) {
            Boolean flag = false;
            List<String> content = new ArrayList<>();
            XWPFParagraph lastParagraph = null;
            List<TargetParagraphInfo> targets = new ArrayList<>();
            for (XWPFParagraph paragraph : document.getParagraphs()) {

                if (paragraph.getStyle() != null && paragraph.getStyle().equals("6")) {
                    flag = true;
                    // 获取原始文本并替换指定字符串
                    String originalText = paragraph.getText();
                    content.add(originalText);

                    // 手动清空段落中的所有 XWPFRun
                    List<XWPFRun> runs = new ArrayList<>(paragraph.getRuns());
                    for (XWPFRun run : runs) {
                        paragraph.removeRun(paragraph.getRuns().indexOf(run));
                    }
                    paragraph.setStyle(null);
                } else {
                    flag = false;
                    if (!CollectionUtils.isEmpty(content)) {

                        questionContent = String.join("\n", content);
                        String result = deepSeekHelpMe(getQuestion(questionContent));
                        data.add(result);

                        TargetParagraphInfo targetParagraphInfo = new TargetParagraphInfo(WordTool.getParagraphIndex(document, lastParagraph), result);
                        targets.add(targetParagraphInfo);
                        content.clear();
                    }
                }
                lastParagraph = paragraph;
            }
            // 执行批量插入
            WordTool.batchInsertAfterParagraphs(document, targets);
            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
                document.write(fos);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        WordTool.test1(outputFilePath);
//        try {
//            String savePath = workSpace + "result" + File.separator + LocalDate.now() + File.separator + "data" + ".json";
//            File saveFile = new File(savePath);
//            if (!saveFile.exists()) {
//                saveFile.getParentFile().mkdirs();
//                saveFile.createNewFile();
//            }
//            FileUtils.writeStringToFile(gson.toJson(data), savePath);
//
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    public void postWordA(String inputFilePath) {
        Gson gson = new Gson();
        File file = new File(inputFilePath);
        String outputFilePath = "C:\\Users\\xjc.ARCVIDEO\\Downloads\\" + file.getName() + "-output.docx";
        String questionContent = null;
        List<String> data = new ArrayList<>();
        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument document = new XWPFDocument(fis)) {
            Boolean flag = false;
            List<String> content = new ArrayList<>();
            XWPFParagraph lastParagraph = null;
            List<TargetParagraphInfo> targets = new ArrayList<>();
            for (XWPFParagraph paragraph : document.getParagraphs()) {

                if (paragraph.getStyle() != null && paragraph.getStyle().equals("6")) {
                    flag = true;
                    // 获取原始文本并替换指定字符串
                    String originalText = paragraph.getText();
                    content.add(originalText);

                    // 手动清空段落中的所有 XWPFRun
                    List<XWPFRun> runs = new ArrayList<>(paragraph.getRuns());
                    for (XWPFRun run : runs) {
                        paragraph.removeRun(paragraph.getRuns().indexOf(run));
                    }
                    paragraph.setStyle(null);
                } else {
                    flag = false;
                    if (!CollectionUtils.isEmpty(content)) {

                        questionContent = String.join("\n", content);
                        String result = deepSeekHelpMe(getQuestion(questionContent));
                        data.add(result);

                        TargetParagraphInfo targetParagraphInfo = new TargetParagraphInfo(WordTool.getParagraphIndex(document, lastParagraph), result);
                        targets.add(targetParagraphInfo);
                        content.clear();
                    }
                }
                lastParagraph = paragraph;
            }
            // 执行批量插入
            WordTool.batchInsertAfterParagraphs(document, targets);
            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
                document.write(fos);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
//       WordTool.test1(outputFilePath);
//        try {
//            String savePath = workSpace + "result" + File.separator + LocalDate.now() + File.separator + "data" + ".json";
//            File saveFile = new File(savePath);
//            if (!saveFile.exists()) {
//                saveFile.getParentFile().mkdirs();
//                saveFile.createNewFile();
//            }
//            FileUtils.writeStringToFile(gson.toJson(data), savePath);
//
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    public String deepSeekHelpMe(String question) {
        Gson gson = new Gson();
        //参数
        DeepSeekRequest request = new DeepSeekRequest();
        request.setModel("deepseek-r1-250120");
        List<DeepSeekMessage> messages = new ArrayList<>();
        DeepSeekMessage message1 = new DeepSeekMessage();
        message1.setRole("system");
        message1.setContent("你是人工智能助手.");
        messages.add(message1);
        DeepSeekMessage message2 = new DeepSeekMessage();
        message2.setRole("user");
        message2.setContent(question);
        messages.add(message2);
        request.setMessages(messages);
        String gsonStr = gson.toJson(request);
        System.out.println("request:" + gsonStr);
        String result = HttpTool.postDeepSeek(gsonStr);
        return JsonUtils.extractContentFromStrJson(result);
    }

    public String picUnstand(String filepath) {
        Gson gson = new Gson();
        List<String> picList = new ArrayList<>();
        File file = new File(filepath);
        String name = file.getName().substring(0, file.getName().length() - 4);
        String targetPicPath = service.getWorkSpace() + "thumbnail" + File.separator + LocalDate.now() + File.separator + name + File.separator;
        File targetPicDir = new File(targetPicPath);
        if (!targetPicDir.exists()) {
            targetPicDir.mkdirs();
        }

        //图片
        List<String> picCodeList = new ArrayList<>();
        picCodeList.add(Tools.readImage(filepath));

        //参数
        Request request = new Request();
        request.setModel("doubao-1-5-vision-pro-32k-250115");
        Message message = new Message();
        message.setRole("user");
        List<Content> content = new ArrayList<>();
        Content question = new Content();
        question.setType("text");
        question.setText("用简洁,专业的语言,给我尽可能多地分析出，界面中存在的接口");
        content.add(question);
        for (String picCode : picCodeList) {
            Content pic = new Content();
            pic.setType("image_url");
            pic.setImage_url(new ImageUrl(picCode));
            content.add(pic);
        }
        message.setContent(content);
        request.setMessages(Collections.singletonList(message));
        String gsonStr = gson.toJson(request);
        System.out.println("request:" + gsonStr);
        String result = HttpTool.post(gsonStr);
        try {
            String savePath = service.getWorkSpace() + "result" + File.separator + LocalDate.now() + File.separator + name + ".json";
            File saveFile = new File(savePath);
            if (!saveFile.exists()) {
                saveFile.getParentFile().mkdirs();
                saveFile.createNewFile();
            }
            FileUtils.writeStringToFile(result, savePath);


        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    public String videoUnderstand(String filepath, String tag) {
        Gson gson = new Gson();
        List<String> picList = new ArrayList<>();
        File file = new File(filepath);
        String name = file.getName().substring(0, file.getName().length() - 4);
        String targetPicPath = service.getWorkSpace() + "thumbnail" + File.separator + LocalDate.now() + File.separator + name + File.separator;
        File targetPicDir = new File(targetPicPath);
        if (!targetPicDir.exists()) {
            targetPicDir.mkdirs();
        }
        try {
            // 实例化工具类，传入FFmpeg的路径
            System.out.println("getFfmpegExcFileName" + service.getFfmpegExcFileName());
            VideoFrameExtractor extractor = new VideoFrameExtractor(service.getFfmpegExcFileName());
            // 每秒抽取1帧
            int framesPerSecond = 1;
            // 调用方法抽取帧
            List<String> frames = extractor.extractFramesV4(filepath, targetPicPath, framesPerSecond);
            for (String frame : frames) {
                picList.add(frame);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //图片
        List<String> picCodeList = new ArrayList<>();
        for (String pic : picList) {
            picCodeList.add(Tools.readImage(pic));
        }
        //参数
        Request request = new Request();
        request.setModel(service.getAIModelName());
        Message message = new Message();
        message.setRole("user");
        List<Content> content = new ArrayList<>();
        Content question = new Content();
        question.setType("text");
//        question.setText("这些图片主要讲了什么内容,请给出一份内容简介以及一份内容标签结果，要求文字简练,用词专业,描述充分");
        if (StringUtils.equals(tag, "体育赛事")) {
            //这些图片是关于一场体育赛事,你作为一个专业足球播报员的角度，说明下视频比赛情况，并指出是几号球员进球成功？主要讲了什么内容,请以此给出一份内容简介要求文字简练,用词专业,描述充分"
            question.setText(service.getSportAIQuestion());
        } else if (StringUtils.equals(tag, "演讲")) {
            question.setText(service.getSpeechAIQuestion());
        } else {
            question.setText(service.getCommonAIQuestion());
        }
        content.add(question);
        for (String picCode : picCodeList) {
            Content pic = new Content();
            pic.setType("image_url");
            pic.setImage_url(new ImageUrl(picCode));
            content.add(pic);
        }
        message.setContent(content);
        request.setMessages(Collections.singletonList(message));
        String gsonStr = gson.toJson(request);
        System.out.println("request:" + gsonStr);
        String result = HttpTool.post(gsonStr);
        try {
            String savePath = service.getWorkSpace() + "result" + File.separator + LocalDate.now() + File.separator + name + ".json";
            File saveFile = new File(savePath);
            if (!saveFile.exists()) {
                saveFile.getParentFile().mkdirs();
                saveFile.createNewFile();
            }
            FileUtils.writeStringToFile(result, savePath);


        } catch (IOException e) {
            e.printStackTrace();
        }
        return JsonUtils.extractContentFromStrJson(result);
    }

    public String audioUnderstand(String targetVoicePath) {
        String url = service.getLocalAddress() + "/api/gateway/common/download?path=" + targetVoicePath;
        String result = BigASRHttpDemo.asr(url);
        return JsonUtils.extractContentFromVoiceJson(result);
    }

    /**
     * 使用通用识别
     *
     * @param filepath
     * @return
     */
    public String videoUnderstandV2(String filepath) {
        Gson gson = new Gson();
        List<String> picList = new ArrayList<>();
        File file = new File(filepath);
        String name = file.getName().substring(0, file.getName().length() - 4);
        String targetPicPath = service.getWorkSpace() + "thumbnail" + File.separator + LocalDate.now() + File.separator + name + File.separator;
        File targetPicDir = new File(targetPicPath);
        if (!targetPicDir.exists()) {
            targetPicDir.mkdirs();
        }
        try {
            // 实例化工具类，传入FFmpeg的路径
            System.out.println("getFfmpegExcFileName" + service.getFfmpegExcFileName());
            VideoFrameExtractor extractor = new VideoFrameExtractor(service.getFfmpegExcFileName());
            // 每秒抽取1帧
            int framesPerSecond = 1;
            // 调用方法抽取帧
            List<String> frames = extractor.extractFramesV3(filepath, targetPicPath, framesPerSecond);
            for (String frame : frames) {
                picList.add(frame);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<String> result = new ArrayList<>();
        for (String pic : picList) {
            try {
                List<String> resp = ocrProcessor.sendOcrRequest(Tools.readImageV2(pic));
                if (!CollectionUtils.isEmpty(resp)) {
                    result.addAll(resp);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        List<String> uniqueList = result.stream().distinct().collect(Collectors.toList());

        //参数
        return "识别结果：\n" + String.join("\n", uniqueList);
    }

//    public String videoUnderstandOld(String filepath) {
//        List<String> result = new ArrayList<>();
//        try {
//            long time = readVideoTimeFromCommand(filepath);
//            Integer dataList = Math.toIntExact(time / 1000);
//            List<String> picList = new ArrayList<>();
//            for (int i = 0; i < dataList; i++) {
//                String outPath = dealThumbnailPic(filepath, (long) i * 1000);
//                if (outPath != null) {
//                    //log.info("抽帧成功：{}", outPath);
//                    String base64 = Tools.readImage(outPath);
//                    if (!StringUtils.isEmpty(base64)) {
//                        picList.add(Tools.readImage(outPath));
//                    }
//                }
//            }
//            HttpService httpService = new HttpService("https://visual.volcengineapi.com", "token");
//            //picList
//            for (String pic : picList) {
//
//            }
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//        return "understandVideo";
//    }

    List<String> entityDetect(List<String> picList) {
        //调用通用实体识别及场景识别
        List<String> result = Arrays.asList("操场运动会", "运动会", "开幕式");
        return result;
    }

    String videoCut(String filepath) {
        //调用通用实体识别及场景识别
        String targetFilePath = "filepath";
        return targetFilePath;
    }

    String dealThumbnailPic(String targetFilePath, String outPath, Long positionStart) {
        /*图片抽帧*/
        String frameTempPicFolder = service.getWorkSpace() + "thumbnail" + File.separator + LocalDate.now();
        File picDir = new File(frameTempPicFolder);
        if (!picDir.exists()) {
            picDir.mkdirs();
        }
        Boolean picFlg = runCommandLine(service.getFfmpegExcFileName(), targetFilePath, outPath, String.valueOf(positionStart), 6000);
        if (picFlg) {
            return outPath;
        } else {
            //抽帧失败时，在对应素材的前1秒中，取任意帧数再次抽帧
            Random numList = new Random();
            //生成一个[0,1000)之间的随机数
            int num = numList.nextInt(1000);
            Boolean tryPicFlg = runCommandLine(service.getFfmpegExcFileName(), targetFilePath, outPath, String.valueOf(num), 6000);
            if (tryPicFlg) {
                return outPath;
            }
            return null;
        }
    }

    //[/usr/local/arcvideo/amam/transcoder/arcvideo.exe -ss 26.920 -i /mnt/data/remote/MAM/material/temp/Upload/2025-04-03/a344358d9c6c7d0e83ae6327674fca0d.mp4 -vf scale=1920:1080 -vframes 1 -y /mnt/data/remote/MAM/temp/snap/2025-04-03/1743652254454.jpg]
    private Boolean runCommandLine(String exefile, String infile, String outfile, String frame, Integer timeout) {
        try {
            String[] command = new String[]{exefile, "-ss", frame, "-i", infile, "-vf scale=120:-1 -vframes 1", "-y", outfile};
            Process process = Runtime.getRuntime().exec(command, null, new File(service.getWorkSpace()));
            process.waitFor();
            process.destroy();
            return Boolean.TRUE;
        } catch (Exception e) {
            //log.error("执行命令时发生异常", e);
            return Boolean.FALSE;
        }
    }

    long readVideoTimeFromCommand(String filePath) throws IOException {
        ProcessBuilder builder = new ProcessBuilder();
        List<String> commands = new ArrayList<>();
        commands.add(service.getFfmpegExcFileName());
        commands.add("-i");
        commands.add(filePath);
        builder.command(commands);
        builder.redirectErrorStream(true);
        Process p = builder.start();
        // 获取执行输出信息
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8));
        StringBuilder outInfo = new StringBuilder();
        String line = "";
        while ((line = br.readLine()) != null) {
            outInfo.append(line);
        }
        br.close();
        // 通过正则获取时长信息
        String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
        Pattern pattern = Pattern.compile(regexDuration);
        Matcher matcher = pattern.matcher(outInfo.toString());
        if (matcher.find()) {
            return getTime(matcher.group(1));
        }
        return 0;
    }

    /**
     * 获取时间毫秒
     *
     * @param time 格式:"00:00:10.68"
     * @return
     */
    private static long getTime(String time) {
        int min = 0;

        String[] strs = time.split(":");
        String ZERO = "00";
        if (strs[0].compareTo(ZERO) > 0) {
            // 秒
            min += Long.parseLong(strs[0]) * 60 * 60 * 1000;
        }
        if (strs[1].compareTo(ZERO) > 0) {
            min += Long.parseLong(strs[1]) * 60 * 1000;
        }
        if (strs[2].compareTo(ZERO) > 0) {
            min += Math.round(Double.parseDouble(strs[2]) * 1000);
        }
        return min;
    }

    String getQuestion(String content) {
        String question = "你是一名产品经理，现在需要采用NESMA功能点分析方法，对avp动态沙盘系统进行功能点分析，需要根据批量输入的功能点，按以下格式输出：\n" +
                "功能点：\n" +
                "功能描述：\n" +
                "输入：\n" +
                "输出：\n" +
                "处理过程：\n" +
                "本事务功能涉及到的数据文件（即FTR/RET）：\n" +
                "xxx表\n" +
                "\n" +
                "示例：\n" +
                "球队周新增数据\n" +
                "功能描述：统计球队在指定周时间段内的新增赛事数据，如新增比赛场次、新增进球数等。\n" +
                "输入：用户选择的球队名称、周时间段。\n" +
                "输出：球队在指定周内的各类新增数据明细及汇总报表。\n" +
                "处理过程：\n" +
                "接收用户输入的球队名称和周时间段。\n" +
                "从赛事数据表中筛选出该球队在指定周内的新增比赛记录。\n" +
                "对新增数据进行分类统计和汇总。\n" +
                "结合基础数据字典表补充数据字段描述。\n" +
                "生成并返回球队周新增数据报表。\n" +
                "本事务功能涉及到的数据文件（即FTR/RET）：\n" +
                "赛事数据表\n" +
                "基础数据字典表\n" +
                "\n" +
                "\n" +
                "请根据下列功能点，按上述要求输出，输出的结果中不能有注释或者备注，且处理过程中不需要数字编号顺序，数据表描述尽量合理，且对应功能点行增加特殊字符串\"##test##\"；\n" +
                content +
                "\n" +
                "\n" +
                "备注：avp动态沙盘系统是基于Apple Vision Pro硬件，通过\"赛事直播+3D动态沙盘\"的创新模式，构建视频内容与实时交互沙盘的双重观赛体验。主要业务流程如下：\n" +
                "1)\t咪咕总控推平面赛事流到AVP动态沙盘系统。\n" +
                "2)\tAVP动态沙盘系统解析平面画面，找寻赛场、球员、裁判、球等关键数据坐标点，并转换为三维平面数据。\n" +
                "3)\tAVP动态沙盘系统按实时更新数据并收录数据。\n" +
                "4)\t门户实时同步AVP动态沙盘系统的赛事数据。\n" +
                "5)\t门户将赛事数据实时传输给客户端。\n" +
                "6）客户端根据接收的数据进行渲染和定时刷新。最终实现客户端的“上帝视角”AI驱动3D赛事沙盘能力。";
        return question;
    }
}
